unit NCore;
interface

const
 CRLF = #13#10;

type
TNPixelFormat = (
   npfMonochrome = $00001001,
   npfGrayscale = $00301001,
   npfRgb = $00303003,
   npfUnused = MaxInt
   );

TNMPosition = (
   Unknown = 0,
   RightThumb = 1,
   RightIndex = 2,
   RightMiddle = 3,
   RightRing = 4,
   RightLittle = 5,
   LeftThumb = 6,
   LeftIndex = 7,
   LeftMiddle = 8,
   LeftRing = 9,
   LeftLittle = 10,
   nmpUnused = MaxInt
   );

TNMImpressionType = (
   LiveScanPlain = 0,
   LiveScanRolled = 1,
   NonliveScanPlain = 2,
   NonliveScanRolled = 3,
   LatentImpression = 4,
   LatentTracing = 5,
   LatentPhoto = 6,
   LatentLift = 7,
   Swipe = 8,
   LiveScanContactless = 9,
   nmiUnused = MaxInt
   );

TNMMinutiaType = (
  nmmtUnknown = 0,
  nmmtEnd = 1,
  nmvfmtBifurcation = 2,
  nmmUnused = MaxInt
  );

TNMMinutia = record
  X: Word;
  Y: Word;
  T: TNMMinutiaType;
  Angle: Byte;
  Quality: Byte;
  Curvature: Byte;
  G: Byte;
end;

TNRgb = record
  Red: Byte;
	  Green: Byte;
	  Blue: Byte;
end;

TNMMinutiaNeighbour = record
  index: LongInt;
  RidgeCount: Byte;
end;

TNIndexPair = record
  Index1: LongInt;
  Index2: LongInt;
end;

TNfeExtractionStatus = (
  nfeesTemplateCreated = 1,
  nfeesTooFewMinutiae = 90,
	nfeesQualityCheckFailed = 100,
	nfeesMatchingFailed = 200,
  nfeesUnused = MaxInt
);

TNleExtractionStatus = (
  nleesNone = 0,
	nleesTemplateCreated = 1,
	nleesFaceNotDetected = 2,
	nleesEyesNotDetected = 3,
	nleesFaceTooCloseToImageBorder = 4,
	nleesQualityCheckGrayscaleDensityFailed = 100,
	nleesQualityCheckExposureFailed = 101,
	nleesQualityCheckSharpnessFailed = 102,
	nleesLivenessCheckFailed = 200,
  nleesGeneralizationFailed = 300,
 nleesUnused = MaxInt
);

TNRect = record
 X: Integer;
 Y: Integer;
 Width: Integer;
 Height: Integer;
end;

TNfeReturnedImage = (
   nferiNone = 0,
   nferiBinarized = 1,
   nferiSkeletonized = 2,
   nferiUnused = MaxInt
);

TNfeTemplateSize = (
   nfetsLarge = 256,
   nfetsSmall = 0,
   nfetsUnused = MaxInt
);

TNleTemplateSize = (
   nletsSmall = 0,
   nletsCompact = 1,
   nletsMedium = 64,
	 nletsLarge = 128,
   nletsUnused = MaxInt
);

TNMSpeed = (
   nmsLow    =   0,
   nmsMedium = 128,
   nmsHigh   = 256
);

TNPoint = record
 X: Integer;
 Y: Integer;
end;

TNSize = record
 Width: Integer;
 Height: Integer;
end;

TNleRotation = record
 Yaw: SmallInt;
 Pitch: SmallInt;
 Roll: SmallInt;
end;

TNleFace = record
 Rectangle: TNRect;
 Rotation: TNleRotation;
 Confidence: Double;
end;

TNleEyes =  record
 First: TNPoint;
 FirstConfidence: Double;
 Second: TNPoint;
 SecondConfidence: Double;
end;

TCameraVideoFormat = record
 FrameWidth: LongInt;
 FrameHeight: LongInt;
 FrameRate: Single;
end;

TNleDetectionDetails = record
 FaceAvailable: Integer;
 Face: TNleFace;
 EyesAvailable: Integer;
 Eyes: TNleEyes;
end;

TMatchResult = record
 FID: Integer;
 FFaceID: String;
 FSimilarity: LongInt;
end;

// Extend this type according to "NMMatchDetails.h" if additional information required
 // i.e. MatedMinutia
TNMMatchDetails = record
   Score: LongInt;
   fingerDetails: Pointer;
   faceDetails: Pointer;
end;

TNLibraryInfo = record
 Title: array[0..127] of Char;
 Product: array[0..127] of Char;
 Company: array[0..63] of Char;
 Copyright: array[0..191] of Char;
 VersionMajor: Integer;
 VersionMinor: Integer;
 VersionBuild: Integer;
 VersionRevision: Integer;
 Activated: array[0..255] of Char;
end;

TArrayOfStrings = array of string;
TArrayOfMatchResult = array of TMatchResult;
TArrayOfPointer = array of Pointer;
TArrayOfLongWord = array of LongWord;
TArrayOfTCameraVideoFormat = array of TCameraVideoFormat;
TArrayOfTNleFace = array of TNleFace;
TArrayOfByte = array of Byte;
TArrayOfArrayOfByte = array of TArrayOfByte;

procedure NCoreGetInfo(var info: TNLibraryInfo);
function  NErrorGetDefaultMessage(err: LongInt): String;
procedure NFree(pBuffer: Pointer);
procedure NObjectFree(hPointer: Pointer);
procedure NObjectReset(hPointer: Pointer);
procedure NObjectCopyParameters(hdstPointer: Pointer; hsrcPointer: Pointer);
procedure NObjectClone(hPointer: Pointer; var hDstPointer: Pointer);

procedure GetParameter(handle: Pointer; parameterId: Integer; var value :Integer); overload;
procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Double); overload;
procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Byte); overload;
procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Boolean); overload;
procedure GetParameter(handle: Pointer; parameterId: Integer; var value: SmallInt); overload;
procedure GetParameter(handle: Pointer; parameterId: Integer; var value: ShortInt); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: Byte); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: Integer); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: Double); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: Boolean); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: SmallInt); overload;
procedure SetParameter(handle: Pointer; parameterId: Integer; value: ShortInt); overload;
procedure GetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; var value: Byte); overload;
procedure GetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; var value: LongWord); overload;
procedure SetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; value: Double); overload;
procedure SetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; value: LongWord); overload;

function  NSucceeded(Res: Integer): Boolean;
function  NFailed(Res: Integer): Boolean;
procedure NRaiseError(Err: Integer);
procedure NCheck(Res: Integer);

implementation

uses NUtils, Types, SysUtils;

const
 dllName = 'NCore.dll';

{$ifdef ver210}
 function  NCoreGetInfoInternal(var info: TNLibraryInfo): Integer stdcall; external dllName name 'NCoreGetInfoW';
 function  NErrorGetDefaultMessageInternalEx(errorCode: LongInt; value: PChar; valueSize: LongWord): Integer stdcall; external dllName name 'NErrorGetDefaultMessageExW';
 function  NObjectGetParameter(obj: Pointer; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectGetParameterExW';
 function  NObjectGetParameterWithPartEx(obj: Pointer; partId: ShortInt; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectGetParameterWithPartExW';
 function  NObjectSetParameterEx(obj: Pointer; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectSetParameterExW';
 function  NObjectSetParameterWithPartEx(obj: Pointer; partId: SmallInt; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectSetParameterWithPartExW';
{$else}
 function  NCoreGetInfoInternal(var info: TNLibraryInfo): Integer stdcall; external dllName name 'NCoreGetInfoA';
 function  NErrorGetDefaultMessageInternalEx(errorCode: LongInt; value: PChar; valueSize: LongWord): Integer stdcall; external dllName name 'NErrorGetDefaultMessageExA';
 function  NObjectGetParameter(obj: Pointer; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectGetParameterExA';
 function  NObjectGetParameterWithPartEx(obj: Pointer; partId: ShortInt; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectGetParameterWithPartExA';
 function  NObjectSetParameterEx(obj: Pointer; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectSetParameterExA';
 function  NObjectSetParameterWithPartEx(obj: Pointer; partId: SmallInt; parameterId: LongWord; typeId: Integer; pValue: Pointer; valueSize: LongWord): Integer stdcall; external dllName name 'NObjectSetParameterWithPartExA';
{$endif}

procedure NFreeInternal(buffer: Pointer); stdcall; external dllName name 'NFree';
procedure NObjectFreeInternal(buffer: Pointer); stdcall; external dllName name 'NObjectFree';
function  NObjectResetInternal(obj: Pointer): Integer stdcall; external dllName name 'NObjectReset';
function  NObjectCopyParametersInternal(hdstPointer: Pointer; hsrcPointer: Pointer): Integer stdcall; external dllName name 'NObjectCopyParameters';
function  NObjectCloneInternal(hPointer: Pointer; var hDstPointer: Pointer): Integer stdcall; external dllName name 'NObjectClone';

procedure GetParameter(handle: Pointer; parameterId: LongWord; pValue: Pointer; valueSize: LongWord); overload;
begin
  NCheck(NObjectGetParameter(handle, parameterId, -1, pValue, valueSize));
end;

procedure SetParameter(handle: Pointer; parameterId: LongWord; pValue: Pointer; valueSize: LongWord); overload;
begin
  NCheck(NObjectSetParameterEx(handle, parameterId, -1, pValue, valueSize));
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: ShortInt); overload;
 var tmp: ShortInt;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 value := tmp;
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Integer); overload;
 var tmp: Integer;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 value := tmp;
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Boolean); overload;
 var tmp: Integer;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 if (tmp = 1) then value := true
 else value := false;
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Double); overload;
 var tmp: Double;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 value := tmp;
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: SmallInt); overload;
 var tmp: SmallInt;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 value := tmp;
end;

procedure GetParameter(handle: Pointer; parameterId: Integer; var value: Byte); overload;
 var tmp: Byte;
begin
 tmp := 0;
 GetParameter(handle, parameterId, @tmp, SizeOf(tmp));
 value := tmp;
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: Byte); overload;
begin
 SetParameter(handle, parameterId, @(value), SizeOf(value));
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: ShortInt); overload;
begin
 SetParameter(handle, parameterId, @(value), SizeOf(value));
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: SmallInt); overload;
begin
 SetParameter(handle, parameterId, @(value), SizeOf(value));
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: Integer); overload;
begin
 SetParameter(handle, parameterId, @(value), SizeOf(value));
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: Boolean); overload;
 var int: Integer;
begin
 int := 0;
 if value = true  then int := 1;
 SetParameter(handle, parameterId, @(int), SizeOf(int));
end;

procedure SetParameter(handle: Pointer; parameterId: Integer; value: Double); overload;
begin
 SetParameter(handle, parameterId, @(value), SizeOf(value));
end;

procedure GetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; var value: Byte); overload;
 var res: Integer;
begin
 res := NObjectGetParameterWithPartEx(handle, parameterType, parameterId, -1, @(value), SizeOf(value));
 NCheck(res);
end;

procedure GetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; var value: LongWord); overload;
 var tmp: Integer;
   res: Integer;
begin
 tmp := 0;
 res := NObjectGetParameterWithPartEx(handle, parameterType, parameterId, -1, @tmp, SizeOf(tmp));
 NCheck(res);
 value := tmp;
end;

procedure GetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; var value: Integer); overload;
 var tmp: Integer;
   res: Integer;
begin
 tmp := 0;
 res := NObjectGetParameterWithPartEx(handle, parameterType, parameterId, -1, @(value), SizeOf(value));
 NCheck(res);
 value := tmp;
end;

procedure SetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; value: Double); overload;
 var res: Integer;
begin
 res := NObjectSetParameterWithPartEx(handle, parameterType, parameterId, -1, @(value), SizeOf(value));
 NCheck(res);
end;

procedure SetParameter(handle: Pointer; parameterType: SmallInt; parameterId: Integer; value: LongWord); overload;
 var res: Integer;
begin
 res := NObjectSetParameterWithPartEx(handle, parameterType, parameterId, -1, @(value), SizeOf(value));
 NCheck(res);
end;

procedure NCoreGetInfo(var info: TNLibraryInfo);
 var res: Integer;
begin
 res := NCoreGetInfoInternal(info);
 NCheck(res);
end;

procedure NFree(pBuffer: Pointer);
begin
 if (pBuffer <> nil) then
 begin
  NFreeInternal(pBuffer);
 end;
end;

procedure NObjectCopyParameters(hdstPointer: Pointer; hsrcPointer: Pointer);
begin
  NCheck(NObjectCopyParametersInternal(hdstPointer, hsrcPointer));
end;

procedure NObjectReset(hPointer: Pointer);
begin
  NCheck(NObjectResetInternal(hPointer));
end;

procedure NObjectFree(hPointer: Pointer);
begin
 if (hPointer <> nil) then
 begin
  NObjectFreeInternal(hPointer);
 end;
end;

procedure NObjectClone(hPointer: Pointer; var hDstPointer: Pointer);
begin
 NCheck(NObjectCloneInternal(hPointer, hDstPointer));
end;

function NErrorGetDefaultMessage(err: LongInt): String;
 var res: Integer;
     str: String;
     point: PChar;
begin
 str := '';
 res := NErrorGetDefaultMessageInternalEx(err, nil, 0);
 if (res > 0) then
 begin
   res := res + 1;
   point := GetMemory(res);
   res := NErrorGetDefaultMessageInternalEx(err, point, res);
   NCheck(res);
   str := string(point);
   FreeMem(point);
 end;
 Result := str;
end;

function NSucceeded(Res: Integer): Boolean;
begin
  Result := Res >= 0;
end;

function NFailed(Res: Integer): Boolean;
begin
  Result := Res < 0;
end;

procedure NRaiseError(Err: Integer);
begin
  raise Exception.CreateFmt('Error:'#13#10' Code = %d'#13#10' ' + NErrorGetDefaultMessage(Err),
    [Err]);
end;

procedure NCheck(Res: Integer);
begin
  if NFailed(Res) then NRaiseError(Res);
end;

end.